package trb.complexshield.benchmarking;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import javax.media.j3d.Geometry;
import javax.media.j3d.IndexedGeometryArray;
import javax.media.j3d.Shape3D;
import no.hrp.hvrc.property.editor.AppearanceProperties;
import no.hrp.hvrc.property.editor.SetDirectly;
import no.hrp.hvrc.utils.j3d.GeometryExtractor;
import no.hrp.hvrc.utils.j3d.Mat4;
import no.hrp.hvrc.utils.j3d.ObjectViewer;
import no.hrp.hvrc.utils.j3d.SGUtils;
import no.hrp.hvrc.utils.j3d.Vec3;
import no.hrp.hvrc.utils.j3d.geometry.Extrusion;
import no.hrp.hvrc.utils.j3d.geometry.ExtrusionUtil;
import no.hrp.hvrc.utils.j3d.geometry.IndexedMesh;
import no.hrp.hvrc.utils.j3d.geometry.IndexedTrianglesGeometry;
import trb.complexshield.ComplexShield;
import trb.complexshield.bool.model.BoolBox;
import trb.complexshield.closedmesh.BvhCollisionMesh;
import trb.complexshield.closedmesh.ClosedMesh;
import trb.complexshield.voxel.VoxelFromBool;

public class BenchmarkBox {

    public static void main(String[] args) {
        IndexedMesh indexedMesh = createIndexedMesh(new BenchmarkBox(new Vec3(-1, 0, -1), new Vec3(1, 2, 1), new Mat4()));
        IndexedGeometryArray geom = new IndexedTrianglesGeometry(indexedMesh).geom;
        AppearanceProperties appearanceProperties = new AppearanceProperties(null, new SetDirectly(), null);
        appearanceProperties.diffuse.set(Color.BLUE);
        ObjectViewer.view(SGUtils.wrapInBrancGroup(new Shape3D(geom, appearanceProperties.createNewAppearance())));
    }

    private final Vec3 lower = new Vec3();
    private final Vec3 upper = new Vec3();
    private final Mat4 mat4 = new Mat4();

    public BenchmarkBox(Vec3 lower, Vec3 upper, Mat4 mat4) {
        this.lower.set(lower);
        this.upper.set(upper);
        this.mat4.set(mat4);
    }

    public static ComplexShield createVoxel(BenchmarkBox box, int dim) {
        return VoxelFromBool.createVoxel(createBoolModel(box), dim);
    }

    public static ComplexShield createBool(BenchmarkBox box) {
        return BenchmarkTub.createComplexShieldFromBoolModel(createBoolModel(box));
    }

    public static Object createBoolModel(BenchmarkBox box) {
        return new BoolBox(box.lower, box.upper, box.mat4);
    }

    public static ClosedMesh createClosedMesh(BenchmarkBox box) {
        IndexedMesh indexedMesh = createIndexedMesh(box);
        return new ClosedMesh(indexedMesh.createCoordinates(), indexedMesh.createIndices(), box.mat4);
    }

    public static BvhCollisionMesh createBvhMesh(BenchmarkBox box) {
        try {
            IndexedMesh indexedMesh = createIndexedMesh(box);
            return new BvhCollisionMesh(indexedMesh.createCoordinates(), indexedMesh.createIndices(), box.mat4);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException("Failed to load tub model");
        }
    }

    public static IndexedMesh createIndexedMesh(BenchmarkBox box) {
        List<Vec3> line = new ArrayList();
        line.add(new Vec3(box.lower.x, box.lower.y, box.lower.z));
        line.add(new Vec3(box.lower.x, box.lower.y, box.upper.z));
        line.add(new Vec3(box.upper.x, box.lower.y, box.upper.z));
        line.add(new Vec3(box.upper.x, box.lower.y, box.lower.z));

        List<Mat4> transformations = new ArrayList();
        transformations.add(new Mat4());
        transformations.add(new Mat4().translate(0, box.upper.y - box.lower.y, 0));

        List<Geometry> cappedExtrusionGeometries = Extrusion.createCappedExtrusionGeometries(line, transformations, false, true);
        Shape3D shape3D = ExtrusionUtil.createShape3D(cappedExtrusionGeometries, Color.BLUE);
        GeometryExtractor geometryExtractor = GeometryExtractor.extractInWorldSpace(shape3D);
        return new IndexedMesh(geometryExtractor.getCoords(), geometryExtractor.getIndices());

    }
}
